package xcmg.device.web.delivery;

import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import xcmg.device.dao.entity.company.CompanyInfoDO;
import xcmg.device.dao.mapper.CompanyInfoMapper;
import xcmg.device.dao.mapper.delivery.DeliveryNoteMapper;
import xcmg.device.infra.AuthCode;
import xcmg.device.infra.BasicController;
import xcmg.device.infra.ErrorCode;
import xcmg.device.infra.enums.DeliveryStatus;
import xcmg.device.service.audit.DeliveryNoteAuditService;
import xcmg.device.service.company.CompanyInfoService;
import xcmg.device.service.crm.util.ActionResultUtil;
import xcmg.device.service.delivery.DeliveryNoteService;
import xcmg.device.service.sale.SaleIntentionService;
import xcmg.device.service.vo.delivery.BusinessOrderAuditParamVO;
import xcmg.device.service.vo.delivery.DeliveryNoteAddVO;
import xcmg.device.service.vo.delivery.DeliveryNoteVO;
import xcmg.device.service.vo.delivery.ManualFinishVO;
import xcmg.device.service.vo.sale.SaleAddVO;
import xcmg.device.service.warehouse.WarehouseDeliveryRecordService;
import xcmg.device.util.DecimalUtil;
import yb.ecp.fast.infra.annotation.FastMappingInfo;
import yb.ecp.fast.infra.infra.ActionResult;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("/deliveryNote")
public class DeliveryNoteController extends BasicController{

    @Autowired
    private DeliveryNoteService deliveryNoteService;
    @Autowired
    private WarehouseDeliveryRecordService warehouseDeliveryRecordService;

    @Autowired
    private SaleIntentionService saleIntentionService;


    @Autowired
    private DeliveryNoteMapper deliveryNoteMapper;

    @Autowired
    private CompanyInfoMapper companyInfoMapper;
    @Autowired
    private DeliveryNoteAuditService deliveryNoteAuditService;
    @Autowired
    private CompanyInfoService companyInfoService;



    @RequestMapping(value = "/add",method = RequestMethod.POST)
    @ApiOperation(value = "增加发货通知")
    @FastMappingInfo(needLogin = true)
    public ActionResult add(@RequestBody DeliveryNoteAddVO deliveryNoteAddVO)throws Exception{
        if(deliveryNoteAddVO == null || StringUtils.isBlank(deliveryNoteAddVO.getHeaderInfo().getId())){
            return actionResult(ErrorCode.IllegalArument);
        }
        SaleAddVO saleAddVO = saleIntentionService.selectByNo(deliveryNoteAddVO.getHeaderInfo().getSaleNo());

        if (null == saleAddVO)
        {
            return actionResult(ErrorCode.SalesBillIsNull);
        }
        if (saleAddVO.getHeaderInfo().getApplyReturn() == 2)//退货申请审核通过，则不可以发货
        {
            return actionResult(ErrorCode.SalesIsApplyReturn);
        }
        String orgId = getOrgId();
        CompanyInfoDO companyInfoDO = companyInfoMapper.item(orgId);
        //塔机添加发货通知单需添加crm单据号
        if (null != companyInfoDO.getSapCode() && "2130".equals(companyInfoDO.getSapCode())){
            deliveryNoteAddVO.getHeaderInfo().setCrmOrder(saleAddVO.getHeaderInfo().getCrmOrder());
        }

        deliveryNoteAddVO.getHeaderInfo().setCreatorId(getUserId());
        deliveryNoteAddVO.getHeaderInfo().setCreateName(getUserName());
        deliveryNoteAddVO.getHeaderInfo().setSupplierOrgId(orgId);
        deliveryNoteAddVO.getHeaderInfo().setStatus(String.valueOf(DeliveryStatus.Saved.getCode()));
        deliveryNoteAddVO.getHeaderInfo().setCashShortAndOver(DecimalUtil.yuan2fenDefauleZero(deliveryNoteAddVO.getHeaderInfo().getCashShortAndOver()));
        ErrorCode ret=ErrorCode.Success;
        try {
            if(!StringUtils.isEmpty(deliveryNoteAddVO.getHeaderInfo().getDeliveryNo())){
                ret=deliveryNoteService.update(deliveryNoteAddVO, getUserId(), orgId);
            }
            else {
                ret=deliveryNoteService.add(deliveryNoteAddVO, getUserId(), orgId,true);
            }
        } catch(Exception e) {
            return new ActionResult(ErrorCode.Failure.getCode(), e.getMessage(), e.getMessage());
        }
        return actionResult(ret);
    }

    @RequestMapping(value = "/delete",method = RequestMethod.POST)
    @ApiOperation(value = "删除发货通知")
    @FastMappingInfo(needLogin = true,code = AuthCode.DeliveryNote.DEL)
    public ActionResult remove(@RequestBody String[] ids){
        if(ids==null||ids.length==0){
            return actionResult(ErrorCode.IllegalArument);
        }
        ErrorCode ret=deliveryNoteService.remove(Arrays.asList(ids));
        return actionResult(ret);
    }

    @RequestMapping(value = "/update",method = RequestMethod.POST)
    @ApiOperation(value = "更新发货通知")
    @FastMappingInfo(needLogin = true)
    public ActionResult update(@RequestBody DeliveryNoteAddVO deliveryNoteAddVO)throws Exception{
        if(deliveryNoteAddVO.getHeaderInfo().getId() == null){
            return actionResult(ErrorCode.DeliveryNoteIdDuplicated);
        }
        deliveryNoteAddVO.getHeaderInfo().setCashShortAndOver(DecimalUtil.yuan2fenDefauleZero(deliveryNoteAddVO.getHeaderInfo().getCashShortAndOver()));
        return actionResult(deliveryNoteService.update(deliveryNoteAddVO, getUserId(), getOrgId()));
    }

    @RequestMapping(value = "/adjust",method = RequestMethod.POST)
    @ApiOperation(value = "调整")
    @FastMappingInfo(needLogin = true)
    public ActionResult adjust(@RequestBody DeliveryNoteAddVO deliveryNoteAddVO)throws Exception{
        if(deliveryNoteAddVO.getHeaderInfo().getId() == null){
            return actionResult(ErrorCode.DeliveryNoteIdDuplicated);
        }
        deliveryNoteAddVO.getHeaderInfo().setCashShortAndOver(DecimalUtil.yuan2fenDefauleZero(deliveryNoteAddVO.getHeaderInfo().getCashShortAndOver()));
        return actionResult(deliveryNoteService.adjust(deliveryNoteAddVO,getOrgId()));
    }

    @RequestMapping(value = "/list",method = RequestMethod.POST)
    @ApiOperation(value = "发货通知列表")
    @FastMappingInfo(needLogin = true)
    public ActionResult listDeliveryNote(@RequestBody SearchCommonVO<DeliveryNoteVO> condition) throws Exception {
        if(condition==null){
            return actionResult(ErrorCode.IllegalArument);
        }
        if(condition.getFilters()==null){
            DeliveryNoteVO filters=new DeliveryNoteVO();
            filters.setSupplierOrgId(getOrgId());
            condition.setFilters(filters);
        }
        else {
            condition.getFilters().setSupplierOrgId(getOrgId());
        }
        String departmentId = getDeptId();
        String orgId = getOrgId();
        PageCommonVO pageCommonVO=deliveryNoteService.list(condition, departmentId,orgId);
        return actionValueResult(pageCommonVO.getPageInfo());
    }

    @RequestMapping(value = "/item",method = RequestMethod.GET)
    @FastMappingInfo(needLogin = true)
    public ActionResult item(String id, boolean isPrint){
        if(StringUtils.isEmpty(id)){
            return actionResult(ErrorCode.IllegalArument);
        }
        return actionResult(ErrorCode.Success,deliveryNoteService.item(id,isPrint));
    }

    @RequestMapping(value = "/itemList",method = RequestMethod.GET)
    @FastMappingInfo(needLogin = true)
    public ActionResult item(String[] ids){
        List<DeliveryNoteAddVO> voList=new ArrayList<>();
        for (String id:ids
             ) {
            DeliveryNoteAddVO deliveryNoteAddVO= deliveryNoteService.item(id,true);
            voList.add(deliveryNoteAddVO);
        }
        return actionResult(ErrorCode.Success,voList);
    }

    /**
     * @Des 获取发货通知单详情信息（打印单据时调用）
     * @Date 2020/12/29 16:50
     * @Author wangzhaoyu
     * @Param [ids]
     * @Return yb.ecp.fast.infra.infra.ActionResult
     */
    @RequestMapping(value = "/itemsPrintInfo",method = RequestMethod.GET)
    @FastMappingInfo(needLogin = true)
    public ActionResult itemsPrintInfo(String[] ids){
        List<DeliveryNoteAddVO> voList=new ArrayList<>();
        for (String id : ids) {
            DeliveryNoteAddVO deliveryNoteAddVO= deliveryNoteService.itemPrintInfo(id,true);
            voList.add(deliveryNoteAddVO);
        }
        return actionResult(ErrorCode.Success,voList);
    }

    @RequestMapping(value = "/submit",method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true)
    public ActionResult submit(@RequestBody DeliveryNoteAddVO model) throws Exception{
        if(model==null){
            return actionResult(ErrorCode.IllegalArument);
        }
        DeliveryNoteVO headerInfo = model.getHeaderInfo();
        SaleAddVO saleAddVO = saleIntentionService.selectByNo(headerInfo.getSaleNo());

        if (null == saleAddVO)
        {
            return actionResult(ErrorCode.SalesBillIsNull);
        }
        if (saleAddVO.getHeaderInfo().getApplyReturn() == 2)//退货申请审核通过，则不可以发货
        {
            return actionResult(ErrorCode.SalesIsApplyReturn);
        }

        String orgId = getOrgId();
        CompanyInfoDO companyInfoDO = companyInfoMapper.item(orgId);
        //塔机添加发货通知单需添加crm单据号
        if (null != companyInfoDO.getSapCode() && "2130".equals(companyInfoDO.getSapCode())){
            headerInfo.setCrmOrder(saleAddVO.getHeaderInfo().getCrmOrder());
        }
        headerInfo.setStatus(String.valueOf(DeliveryStatus.Submit.getCode()));
        headerInfo.setCreatorId(getUserId());
        headerInfo.setCreateName(getUserName());
        headerInfo.setSupplierOrgId(getOrgId());
        headerInfo.setCashShortAndOver(DecimalUtil.yuan2fenDefauleZero(headerInfo.getCashShortAndOver()));
        ErrorCode ret=ErrorCode.Success;
        try {
            if(!StringUtils.isEmpty(headerInfo.getDeliveryNo())){
                ret=deliveryNoteService.update(model, getUserId(), getOrgId());
            }
            else {
                ret=deliveryNoteService.add(model, getUserId(), getOrgId(),true);
            }
        } catch (Exception e ) {
            return new ActionResult(ErrorCode.Failure.getCode(), e.getMessage(), e.getMessage());
        }

        return actionResult(ret);
    }

    @RequestMapping(value = "/export",method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true)
    @ApiOperation(value = "导出")
    public void export(String[] materialsIds)throws Exception {
        deliveryNoteService.export(Arrays.asList(materialsIds));
    }

    @RequestMapping(value = "/exportAll", method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true)
    @ApiOperation(value = "导出全部")
    public void exportAll(DeliveryNoteVO condition) throws Exception {
        condition.setCreatorId(getUserId());
        deliveryNoteService.exportAll(condition);
    }

//    @RequestMapping(value = "/sapPost",method = RequestMethod.GET)
//    @FastMappingInfo(needLogin = true)
//    @ApiOperation(value = "过账")
//    public ActionResult sapPost(String id)throws Exception {
//        ErrorCode ret;
//        try{
//            String orgId = getOrgId();
//            boolean sapNoPostOrg = sapCommonService.sapNoPostOrg(orgId);
//            if(sapNoPostOrg){
//                return ActionResultUtil.errorActionResult(ErrorCode.IllegalArument.getCode(),"不允许过账");
//            }
//            ret=deliveryNoteService.postSap(id, orgId,getUserId(),getUserName());
//        }catch (Exception e){
//            LogHelper.error(getExceptionAllinformation(e), 1);
//            return new ActionResult(1, e.getMessage());
//        }
//        return actionResult(ret);
//    }

//    @RequestMapping(value = "/sapRemove",method = RequestMethod.GET)
//    @FastMappingInfo(needLogin = true)
//    @ApiOperation(value = "删除过账单")
//    public ActionResult sapRemove(String id)throws Exception {
//        ErrorCode ret=deliveryNoteService.sapRemove(id,getOrgId());
//        return actionResult(ret);
//    }

//    @RequestMapping(value = "/sapReverse",method = RequestMethod.POST)
//    @ApiOperation("发货通知单调用SAP冲销接口")
//    @FastMappingInfo(needLogin = true,code =AuthCode.SaleReverse.DEL)
//    public ActionResult sapReverse(@RequestBody DeliveryNoteVO condition)throws Exception{
//        if(condition == null || StringUtil.isNullOrEmpty(condition.getDeliveryNo())){
//            return actionResult(ErrorCode.IllegalArument);
//        }
//        ErrorCode code;
//        String orgId = getOrgId();
//        try {
//            CompanyInfoDO companyInfo = companyInfoService.getByOrgId(orgId);
//            code = sapCommonService.sapSaleReverse(condition.getDeliveryNo(), companyInfo);
//        }catch (Exception e){
//            return new ActionResult(ErrorCode.Failure.getCode(), e.getMessage());
//        }
//
//        try {
//            boolean sapNoPostOrg = sapCommonService.sapNoPostOrg(orgId);
//            // 过账后对应的发货通知单也要过账，不需要在一个事务中，如果异常过账失败了还可以手动继续过账
//            DeliveryNoteDO deliveryNoteDO = deliveryNoteMapper.itemByNo(condition.getDeliveryNo(), orgId);
//            if (DeliveryNoteDO.POSTING_NO.equals(deliveryNoteDO.getIsPosting()) && !sapNoPostOrg) {
//                deliveryNoteService.postSap(deliveryNoteDO.getId(), orgId, getUserId(), getUserName());
//            }
//        } catch (Exception e) {
//            return new ActionResult(ErrorCode.Failure.getCode(), "冲销单过账成功，但是对应的发货通知单过账失败。" + e.getMessage());
//        }
//
//        return actionResult(code);
//    }

    @RequestMapping(value = "/manualFinish", method = RequestMethod.POST)
    @ApiOperation("手动完成发货单")
    public ActionResult manualFinish(@RequestBody ManualFinishVO manualFinishVO) throws Exception {
        String orgId = getOrgId();
        String billNo = manualFinishVO.getBillNo();
        String materialsNo = manualFinishVO.getMaterialsNo();
        Integer deliveryRecordCount = warehouseDeliveryRecordService.getDeliveryRecordCount(orgId, billNo, materialsNo);
        if (deliveryRecordCount == null || deliveryRecordCount.compareTo(0) <= 0) {
            return ActionResultUtil.errorActionResult(ErrorCode.Failure.getCode(),"发货通知单出库数量等于0，不允许结单！");
        }
        return actionResult(deliveryNoteService.manualFinish(billNo, manualFinishVO.getMaterialsNo(), orgId));
    }


    @RequestMapping(value = "/exportDetails",method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true)
    @ApiOperation(value = "导出零件详细")
    public void exportDetails(String[] ids)throws Exception {
        deliveryNoteService.exportDetails(Arrays.asList(ids));
    }
    @RequestMapping(value = "/exportDetailsAll",method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true)
    @ApiOperation(value = "导出零件详细全部")
    public void exportDetailsAll(DeliveryNoteVO condition)throws Exception {
        condition.setSupplierOrgId(getOrgId());
        deliveryNoteService.exportDetailsAll(condition);
    }

    @RequestMapping(value = "/updateIsReady", method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true)
    public ActionResult updateIsReady(@RequestBody String[] ids) {
        try {
            return actionResult(deliveryNoteService.updateIsReady(Arrays.asList(ids)));
        }catch (Exception e){
            return new ActionResult(ErrorCode.Failure.getCode(), e.getMessage());
        }
    }

    private String getExceptionAllinformation(Exception ex){
        String sOut = ex.getMessage()+"\r\n";
        StackTraceElement[] trace = ex.getStackTrace();
        for (StackTraceElement s : trace) {
            sOut += "\tat " + s + "\r\n";
        }
        return sOut;
    }

    /**
     * @Des 发货通知单审核通过
     * @Date 2021/4/12 10:27
     * @Author wangzhaoyu
     * @Param [param]
     * @Return yb.ecp.fast.infra.infra.ActionResult
     */
    @PostMapping("/auditPass")
    @FastMappingInfo(needLogin = true)
    public ActionResult auditPass(@RequestBody BusinessOrderAuditParamVO param){
        try{
            String userId = getUserId();
            String userName = getUserName();
            ActionResult audit = deliveryNoteAuditService.audit(param,userId,userName,true);
            return audit;
        }catch (Exception e){
            return ActionResultUtil.errorActionResult(ErrorCode.Failure.getCode(),e.getMessage());
        }
    }


    /**
     * @Des 发货通知单审核拒绝
     * @Date 2021/4/12 10:27
     * @Author wangzhaoyu
     * @Param [param]
     * @Return yb.ecp.fast.infra.infra.ActionResult
     */
    @PostMapping("/auditReject")
    @FastMappingInfo(needLogin = true)
    public ActionResult auditReject(@RequestBody BusinessOrderAuditParamVO param){
        try{
            String userId = getUserId();
            String userName = getUserName();
            ActionResult audit = deliveryNoteAuditService.audit(param,userId,userName,false);
            return audit;
        }catch (Exception e){
            return ActionResultUtil.errorActionResult(ErrorCode.Failure.getCode(),e.getMessage());
        }
    }

    /**
     * @Des 主页面数据看板--发货通知单待审核数据
     * @Date 2021/4/13 11:21
     * @Author wangzhaoyu
     * @Param []
     * @Return yb.ecp.fast.infra.infra.ActionResult
     */
    @RequestMapping(value = "/mainBoardWaitAudit" , method = RequestMethod.GET)
    @FastMappingInfo(needLogin = true)
    public ActionResult mainBoardWaitAudit() throws Exception {
        String orgId = getOrgId();
        //查询当前机构未删除，已提交的待审核数据
        Integer waitDataCount = deliveryNoteService.countAuditData(orgId);
        return ActionResultUtil.successActionResult(waitDataCount);
    }
}
